package com.heking.security.ssl;

import android.content.Context;

import com.heking.security.SecurityUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;

/**
 * 证书生成工厂
 *
 * @Author 35574
 * @Date 2021/10/12
 * @Description
 */
public class ZCertificateFactory {
    private CertificateFactory certificateFactory;

    private ZCertificateFactory(CertificateFactory certificateFactory) {
        this.certificateFactory = certificateFactory;
    }

    /**
     * 根据证书类型获取证书工厂是咧
     *
     * @param certificateType 证书类型 {@link SSLConstants#CERTIFICATE_TYPE_X509}
     * @return
     * @throws CertificateException
     */
    public static ZCertificateFactory getInstance(String certificateType) throws CertificateException {
        return new ZCertificateFactory(CertificateFactory.getInstance(certificateType));
    }

    /**
     * 生成证书实例 Certificate
     *
     * @param ins 证书文件流
     * @return Certificate
     * @throws CertificateException
     */
    public Certificate generateCertificate(InputStream ins) throws CertificateException {
        return certificateFactory.generateCertificate(ins);
    }

    /**
     * 使用assets文件夹下的证书文件生成证书实例
     *
     * @param context
     * @param assetsPath assets目录下的证书文件的相对路径, eg:certificates/baidumap.cer
     * @return Certificate
     * @throws CertificateException
     * @throws IOException
     */
    public Certificate generateCertificate(Context context, @NonNull String assetsPath) throws CertificateException, IOException {
        return certificateFactory.generateCertificate(context.getAssets().open(assetsPath));
    }

    /**
     * 使用assets文件夹下的证书文件生成证书实例集合
     *
     * @param context
     * @param assetsPaths assets目录下的证书文件的相对路径集合, eg:certificates/baidumap.cer
     * @return Certificates
     * @throws CertificateException
     * @throws IOException
     */
    public List<Certificate> generateCertificates(Context context, @NonNull List<String> assetsPaths) throws CertificateException, IOException {
        List<Certificate> certificates = new ArrayList<>();
        for (int i = 0; i < assetsPaths.size(); i++) {
            certificates.add(generateCertificate(context, assetsPaths.get(i)));
        }
        return certificates;
    }

    /**
     * 根据文件路径生成证书集合
     *
     * @param cerAbsPaths 绝对路径
     * @return
     */
    public List<Certificate> generateCertificates(List<String> cerAbsPaths) {
        List<Certificate> cers = null;
        if (cerAbsPaths != null && cerAbsPaths.size() > 0) {
            cers = new ArrayList<>();
            for (String item : cerAbsPaths) {
                if (item != null) {
                    File file = new File(item);
                    if (file.exists()) {
                        FileInputStream fis = null;
                        try {
                            fis = new FileInputStream(file);
                            Certificate certificate = certificateFactory.generateCertificate(fis);
                            if (certificate != null) {
                                cers.add(certificate);
                            }
                        } catch (FileNotFoundException | CertificateException e) {
                            e.printStackTrace();
                        } finally {
                            SecurityUtils.close(fis);
                        }

                    }
                }
            }
        }
        return cers;
    }


}
